import { _decorator, Component, Node, tween, Vec3, v3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('NodeMovementController')
export class NodeMovementController extends Component {

    @property(Vec3)
    startPos: Vec3 = new Vec3(0, 0, 0); // 起始位置
    @property(Vec3)
    endPos: Vec3 = new Vec3(10, 0, 0); // 结束位置
    @property
    height: number = 5; // 抛物线最大高度
    @property
    duration: number = 2; // 动画持续时间（秒）
    @property
    delayBetween: number = 0.2; // 节点间启动延迟

    @property([Node])
    movingNodes: Node[] = []; // 要移动的节点数组

    private originalPositions: Map<Node, Vec3> = new Map();

    onLoad() {
        // 保存原始位置
        this.movingNodes.forEach(node => {
            this.originalPositions.set(node, node.position.clone());
        });
    }

    start() {
        // this.playParabolaAnimation();


        const node = this.node;
        const jumpDuration = 0.1; // 上升和下降各占一半时间
        const distance = 50;
        const height = 200;

        // 上升阶段
        tween(node)
            .by(jumpDuration, {
                position: v3(distance / 2, height, 0),
            }, { easing: 'sineOut' }) // 使用缓动函数使上升更自然
            .call(() => {
                // 下降阶段
                tween(node)
                    .by(jumpDuration, {
                        position: v3(distance / 2, -height, 0),
                    }, { easing: 'sineIn' })
                    .start();
            })
            .start();
    }



    // 播放所有节点的抛物线动画
    playParabolaAnimation() {
        this.movingNodes.forEach((node, index) => {
            this.scheduleOnce(() => {
                this.moveNodeWithParabola(node, this.startPos, this.endPos);
            }, index * this.delayBetween);
        });
    }

    // 单个节点的抛物线移动
    moveNodeWithParabola(node: Node, start: Vec3, end: Vec3) {
        // 重置位置到起点
        node.position = start.clone();

        const startData = { progress: 0 };

        tween(startData)
            .to(this.duration, { progress: 1 }, {
                onUpdate: (target) => {
                    const position = this.calculateParabolaPosition(
                        start,
                        end,
                        target.progress,
                        this.height
                    );
                    node.position = position;

                    // 可选：根据进度旋转节点
                    this.rotateNode(node, target.progress);

                    // 可选：根据进度缩放节点
                    this.scaleNode(node, target.progress);
                },
                easing: 'linear'
            })
            .call(() => {
                console.log(`${node.name} 抛物线移动完成`);
            })
            .start();
    }

    // 计算抛物线位置
    calculateParabolaPosition(start: Vec3, end: Vec3, progress: number, height: number): Vec3 {
        // 水平方向线性插值
        const horizontalPos = new Vec3();
        Vec3.lerp(horizontalPos, start, end, progress);

        // 抛物线高度计算 (二次函数)
        // y = -4 * height * (x^2 - x) + start.y
        // 其中 x = progress
        const y = -4 * height * (progress * progress - progress) + start.y;

        return new Vec3(horizontalPos.x, y, horizontalPos.z);
    }

    // 节点旋转（朝向运动方向）
    rotateNode(node: Node, progress: number) {
        if (progress > 0.01) {
            const prevProgress = progress - 0.01;
            const prevPos = this.calculateParabolaPosition(
                this.startPos,
                this.endPos,
                prevProgress,
                this.height
            );

            const currentPos = node.position;
            const direction = new Vec3();
            Vec3.subtract(direction, currentPos, prevPos);

            if (direction.lengthSqr() > 0.01) {
                direction.normalize();
                node.forward = direction;
            }
        }
    }

    // 节点缩放（模拟远近效果）
    scaleNode(node: Node, progress: number) {
        // 在顶点时最大，起点和终点最小
        const scaleFactor = 0.8 + 0.4 * Math.sin(Math.PI * progress);
        node.setScale(scaleFactor, scaleFactor, scaleFactor);
    }

    // 重置所有节点位置
    resetAllNodes() {
        this.movingNodes.forEach(node => {
            const originalPos = this.originalPositions.get(node);
            if (originalPos) {
                node.position = originalPos.clone();
            }
        });
    }

    // 动态设置目标位置
    setTargetPosition(position: Vec3) {
        this.endPos = position.clone();
    }

    // 动态添加移动节点
    addMovingNode(node: Node) {
        if (!this.movingNodes.includes(node)) {
            this.movingNodes.push(node);
            this.originalPositions.set(node, node.position.clone());
        }
    }
}


